package com.ruoyi.web.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.domain.WorkForm;
import com.ruoyi.web.domain.WorkFormAttachment;
import com.ruoyi.web.domain.WorkFormSupplement;
import com.ruoyi.web.domain.dto.FormExportFilterDto;
import com.ruoyi.web.domain.dto.PushMessageDto;
import com.ruoyi.web.domain.dto.WorkFormDto;
import com.ruoyi.web.domain.dto.WorkFormExportDto;
import com.ruoyi.web.domain.vo.*;
import com.ruoyi.web.mapper.SysAreaMapper;
import com.ruoyi.web.mapper.WorkFormMapper;
import com.ruoyi.web.service.PushMessageService;
import com.ruoyi.web.service.WorkFormAttachmentService;
import com.ruoyi.web.service.WorkFormService;
import com.ruoyi.web.service.WorkFormSupplementService;
import com.ruoyi.web.util.AESUtils;
import com.ruoyi.websocket.WebSocketManager;
import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 工单表 服务实现类
 * </p>
 *
 * @author
 * @since 2025-03-10
 */
@Service
@Slf4j
public class WorkFormServiceImpl extends ServiceImpl<WorkFormMapper, WorkForm> implements WorkFormService {

    /**
     * 全部数据权限
     */
    public static final String DATA_SCOPE_ALL = "1";

    /**
     * 自定数据权限
     */
    public static final String DATA_SCOPE_CUSTOM = "2";

    /**
     * 部门数据权限
     */
    public static final String DATA_SCOPE_DEPT = "3";

    /**
     * 部门及以下数据权限
     */
    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";

    /**
     * 仅本人数据权限
     */
    public static final String DATA_SCOPE_SELF = "5";

    /**
     * 省级账号数据权限
     */
    public static final String DATA_SCOPE_PROVINCE_LEVEL = "01";

    /**
     * 市级账号数据权限
     */
    public static final String DATA_SCOPE_CITY_LEVEL = "02";

    /**
     * 区县级账号数据权限
     */
    public static final String DATA_SCOPE_COUNTY_LEVEL = "03";

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private SysAreaMapper sysAreaMapper;
    @Autowired
    private PushMessageService pushMessageService;
    @Autowired
    private WorkFormAttachmentService workFormAttachmentService;
    @Autowired
    private WorkFormSupplementService workFormSupplementService;
    @Autowired
    private WorkFormMapper workFormMapper;

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public void infoDeptApply(WorkFormDto dto) {
        try {
            Boolean isEncrypted = dto.getIsEncrypted();
            if (isEncrypted == null ? false : isEncrypted) {
                String cipherText = dto.getCipherText();
                String aesDecrypted = AESUtils.decryptBase64(cipherText, AESUtils.getAESSecretKey());
                dto = JSON.parseObject(aesDecrypted, WorkFormDto.class);
//                ObjectMapper om = new ObjectMapper();
//                workForm = om.readValue(aesDecrypted, WorkForm.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        WorkForm workForm = new WorkForm();
        BeanUtils.copyProperties(dto, workForm);
        Long userId = SecurityUtils.getUserId();
        workForm.setCreateBy(String.valueOf(userId));
        workForm.setRegisterTime(LocalDateTime.now());
        workForm.setCreateTime(LocalDateTime.now());
        workForm.setUpdateTime(LocalDateTime.now());
        workForm.setMiddleDispatchDeptId("102");
        this.save(workForm);

        List<WorkFormAttachment> attachments = dto.getAttachments();
        if (attachments != null && attachments.size() > 0) {
            // 存储附件
            List<WorkFormAttachment> attachmentList = attachments.stream().peek(i -> i.setFormId(workForm.getBaseId())).collect(Collectors.toList());
            workFormAttachmentService.saveBatch(attachmentList);
        }

        // 查询当前用户的企业名称是否存在，若不存在则同步更新上
        SysUser byId = sysUserService.selectUserById(userId);
        if (StringUtils.isBlank(byId.getNickName())) {
            sysUserService.update(new LambdaUpdateWrapper<SysUser>().eq(SysUser::getUserId, userId).set(SysUser::getNickName, workForm.getEnterpriseName()));
        }

        // 对于爱山东用户进入我们系统无省市区信息的情况，在提交诉求时需要将填写的省市区信息同步保存到用户信息中
        Boolean isSaveUserArea = workForm.getIsSaveUserArea();
        if (isSaveUserArea == null ? false : isSaveUserArea) {
            List<String> areaNameList = Arrays.asList(workForm.getProvince(), workForm.getCity());
            List<String> areaCodeList = sysAreaMapper.selectAreaCodeByAreaName(areaNameList);
            String districtCode = sysAreaMapper.selectCodeByNameAndParentCode(workForm.getCounty(), areaCodeList.get(1));
            sysUserService.update(new LambdaUpdateWrapper<SysUser>().eq(SysUser::getUserId, userId).set(SysUser::getProvince, areaCodeList.get(0))
                    .set(SysUser::getCity, areaCodeList.get(1)).set(SysUser::getDistrict, districtCode));
        }

        // 将最新大屏数据推送给前端(位于city)
        String province = workForm.getProvince();
        String city = workForm.getCity();
        LargeScreenDataVo largeScreenDataVo = new LargeScreenDataVo();
        HistogramVo appealTypesCount = getAppealTypesCount(province, city, null);
        Map<String, Object> counts = getCounts(province, city, null);
        List<PieChartVo> serviceStatesCount = getServiceStatesCount(province, city, null);
        HistogramVo citiesAppealQuantityCount = getCitiesAppealQuantityCount(province, city, null);
        largeScreenDataVo.setAppealType(appealTypesCount);
        largeScreenDataVo.setProblemTotal((Long) counts.get("problemTotal"));
        BigDecimal settledRate = (BigDecimal) counts.get("settledRate");
        largeScreenDataVo.setSettledRate(settledRate.longValue());
        largeScreenDataVo.setServiceState(serviceStatesCount);
        largeScreenDataVo.setCitiesAppealQuantity(citiesAppealQuantityCount);
        // 将最新的五条诉求通过WebSocket推送给前端
        List<WorkForm> list = this.list(new LambdaQueryWrapper<WorkForm>().eq(WorkForm::getStatus, Byte.parseByte("0")).orderByDesc(WorkForm::getCreateTime).last("LIMIT 1"));
        List<WorkFormLargeScreenRollVo> collect = list.stream().map(i -> {
            WorkFormLargeScreenRollVo workFormLargeScreenRollVo = new WorkFormLargeScreenRollVo();
            workFormLargeScreenRollVo.setEnterpriseName(i.getEnterpriseName());
            workFormLargeScreenRollVo.setProblemDescription(i.getProblemDescription());
            String countyArea = i.getCounty();
            String cityArea = i.getCity();
            if (StringUtils.isNotBlank(cityArea)) {
                countyArea = cityArea + "-" + countyArea;
            }
            workFormLargeScreenRollVo.setArea(countyArea);
            return workFormLargeScreenRollVo;
        }).collect(Collectors.toList());
        largeScreenDataVo.setWorkFormLargeScreenRollList(collect);
        Gson gson1 = new GsonBuilder().serializeNulls().create();
        String largeScreenDataResultJsonWithDataCity = gson1.toJson(largeScreenDataVo);
        LargeScreenDataVo largeScreenDataVo1 = new LargeScreenDataVo();
        largeScreenDataVo1.setWorkFormLargeScreenRollList(collect);
        Gson gson2 = new GsonBuilder().serializeNulls().create();
        String largeScreenDataResultJsonWithoutData = gson2.toJson(largeScreenDataVo1);

        // 对位于city的sessionKeys推送大屏数据
        Set<String> sessionKeys = WebSocketManager.getSessionKeysByArea(city);
        for (String sessionKey : sessionKeys) {
            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJsonWithDataCity);
        }

        // 将最新大屏数据推送给前端(位于province)
        LargeScreenDataVo largeScreenDataVo2 = new LargeScreenDataVo();
        HistogramVo appealTypesCount2 = getAppealTypesCount(province, null, null);
        Map<String, Object> counts2 = getCounts(province, null, null);
        List<PieChartVo> serviceStatesCount2 = getServiceStatesCount(province, null, null);
        HistogramVo citiesAppealQuantityCount2 = getCitiesAppealQuantityCount(province, null, null);
        largeScreenDataVo2.setAppealType(appealTypesCount2);
        largeScreenDataVo2.setProblemTotal((Long) counts2.get("problemTotal"));
        BigDecimal settledRate2 = (BigDecimal) counts2.get("settledRate");
        largeScreenDataVo2.setSettledRate(settledRate2.longValue());
        largeScreenDataVo2.setServiceState(serviceStatesCount2);
        largeScreenDataVo2.setCitiesAppealQuantity(citiesAppealQuantityCount2);
        // 将最新的五条诉求通过WebSocket推送给前端
        largeScreenDataVo2.setWorkFormLargeScreenRollList(collect);
        Gson gson3 = new GsonBuilder().serializeNulls().create();
        String largeScreenDataResultJsonWithDataProvince = gson3.toJson(largeScreenDataVo2);

        // 对位于province的sessionKeys推送大屏数据
        Set<String> sessionKeys1 = WebSocketManager.getSessionKeysByArea(province);
        for (String sessionKey : sessionKeys1) {
            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJsonWithDataProvince);
        }

        Set<String> provinceAndCitySessionKeys = new HashSet<>(sessionKeys);
        provinceAndCitySessionKeys.addAll(sessionKeys1);

        Set<String> otherSessionKeys = WebSocketManager.getOtherSessionKeys(provinceAndCitySessionKeys);
        for (String sessionKey : otherSessionKeys) {
            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJsonWithoutData);
        }
    }

    @Override
    public WorkFormVo getDetail(String baseId) {
        WorkForm workForm = this.getById(Long.parseLong(baseId));
        WorkFormVo workFormVo = new WorkFormVo();
        BeanUtils.copyProperties(workForm, workFormVo);
        SysUser sysUser = sysUserService.selectUserById(Long.valueOf(workForm.getCreateBy()));
        workFormVo.setCreateByName(sysUser.getUserName());
        // 查询省市区编码
        workFormVo.setProvinceCode(sysAreaMapper.queryCodeByName(workForm.getProvince()));
        workFormVo.setCityCode(sysAreaMapper.selectCodeByNameAndParentCode(workForm.getCity(),workFormVo.getProvinceCode()));
        workFormVo.setCountyCode(sysAreaMapper.selectCodeByNameAndParentCode(workForm.getCounty(), workFormVo.getCityCode()));
        // 查询企业性质
        workFormVo.setCompanyProp(this.baseMapper.queryCompanyProp(workForm.getEnterpriseName()));
        List<WorkFormAttachment> attachments = workFormAttachmentService.list(new LambdaQueryWrapper<WorkFormAttachment>().eq(WorkFormAttachment::getFormId, Long.parseLong(baseId)).orderByAsc(WorkFormAttachment::getSort));
        workFormVo.setAttachments(attachments);
        List<WorkFormSupplement> supplements = workFormSupplementService.list(new LambdaQueryWrapper<WorkFormSupplement>().eq(WorkFormSupplement::getFormId, Long.parseLong(baseId)).orderByAsc(WorkFormSupplement::getSort));
        workFormVo.setSupplements(supplements);
        return workFormVo;
    }

    @Override
    public void generalDeptSend(WorkFormDto dto) {
        WorkForm workForm = new WorkForm();
        BeanUtils.copyProperties(dto, workForm);
        workForm.setDispatchTime(LocalDateTime.now());
        workForm.setStatus(Byte.valueOf("1"));
        workForm.setDispatchAuditStatus("0");
        this.updateById(workForm);
//        //状态变更推送消息
//        pushMessage();
//        //将最新大屏数据推送给前端
//        WorkForm byId = this.getById(dto.getBaseId());
//        String province = byId.getProvince();
//        String city = byId.getCity();
//        LargeScreenDataVo largeScreenDataVo = new LargeScreenDataVo();
//        List<PieChartVo> serviceGradesCount = getServiceGradesCount(province, city, null);
//        List<PieChartVo> serviceStatesCount = getServiceStatesCount(province, city, null);
//        largeScreenDataVo.setServiceGrade(serviceGradesCount);
//        largeScreenDataVo.setServiceState(serviceStatesCount);
//        Gson gson1 = new GsonBuilder().serializeNulls().create();
//        String largeScreenDataResultJson1 = gson1.toJson(largeScreenDataVo);
//        Set<String> sessionKeys1 = WebSocketManager.getSessionKeysByArea(city);
//        for (String sessionKey : sessionKeys1) {
//            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJson1);
//        }
//
//        //将最新大屏数据推送给前端
//        LargeScreenDataVo largeScreenDataVo1 = new LargeScreenDataVo();
//        List<PieChartVo> serviceGradesCount1 = getServiceGradesCount(province, null, null);
//        List<PieChartVo> serviceStatesCount1 = getServiceStatesCount(province, null, null);
//        largeScreenDataVo1.setServiceGrade(serviceGradesCount1);
//        largeScreenDataVo1.setServiceState(serviceStatesCount1);
//        Gson gson2 = new GsonBuilder().serializeNulls().create();
//        String largeScreenDataResultJson2 = gson2.toJson(largeScreenDataVo1);
//        Set<String> sessionKeys2 = WebSocketManager.getSessionKeysByArea(province);
//        for (String sessionKey : sessionKeys2) {
//            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJson2);
//        }
    }

    @Override
    public void reviewSending(WorkFormDto dto) {
        List<Long> formIdList = dto.getFormIdList();
        if (formIdList != null && formIdList.size() > 0) {
            String dispatchAuditStatus = dto.getDispatchAuditStatus();
            LambdaUpdateWrapper<WorkForm> updateWrapper = new LambdaUpdateWrapper<WorkForm>().in(WorkForm::getBaseId, formIdList).set(WorkForm::getDispatchAuditStatus, dispatchAuditStatus).set(WorkForm::getDispatchAuditTime, LocalDateTime.now());
            if (dispatchAuditStatus.equals("1")) {
                updateWrapper.set(WorkForm::getIsConfirm, "0");
            }
            this.update(updateWrapper);
            if (StrUtil.equals(dispatchAuditStatus, "1")) {
                //状态变更推送消息
                pushMessage();
                // 推送相应地区诉求的服务状态、服务等级的变更消息至大屏端
                List<WorkForm> formList = this.list(new LambdaQueryWrapper<WorkForm>().in(WorkForm::getBaseId, formIdList));
                for (WorkForm workForm : formList) {
                    String province = workForm.getProvince();
                    String city = workForm.getCity();
                    LargeScreenDataVo largeScreenDataVo = new LargeScreenDataVo();
                    List<PieChartVo> serviceGradesCount = getServiceGradesCount(province, city, null);
                    List<PieChartVo> serviceStatesCount = getServiceStatesCount(province, city, null);
                    largeScreenDataVo.setServiceGrade(serviceGradesCount);
                    largeScreenDataVo.setServiceState(serviceStatesCount);
                    Gson gson1 = new GsonBuilder().serializeNulls().create();
                    String largeScreenDataResultJson1 = gson1.toJson(largeScreenDataVo);
                    Set<String> sessionKeys1 = WebSocketManager.getSessionKeysByArea(city);
                    for (String sessionKey : sessionKeys1) {
                        WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJson1);
                    }

                    //将最新大屏数据推送给前端
                    LargeScreenDataVo largeScreenDataVo1 = new LargeScreenDataVo();
                    List<PieChartVo> serviceGradesCount1 = getServiceGradesCount(province, null, null);
                    List<PieChartVo> serviceStatesCount1 = getServiceStatesCount(province, null, null);
                    largeScreenDataVo1.setServiceGrade(serviceGradesCount1);
                    largeScreenDataVo1.setServiceState(serviceStatesCount1);
                    Gson gson2 = new GsonBuilder().serializeNulls().create();
                    String largeScreenDataResultJson2 = gson2.toJson(largeScreenDataVo1);
                    Set<String> sessionKeys2 = WebSocketManager.getSessionKeysByArea(province);
                    for (String sessionKey : sessionKeys2) {
                        WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJson2);
                    }
                }
            }
        }
    }

    @Override
    public List<WorkForm> workFormList(WorkFormDto dto) {
        Long userId = SecurityUtils.getUserId();
        String deptId = SecurityUtils.getDeptId();
        boolean admin = SecurityUtils.isAdmin(userId);
        QueryWrapper<WorkForm> wrapper = new QueryWrapper<>();
        String type = dto.getType();
        if(!admin){
            //不是综合组
            if("0".equals(type)){
//                //填写工单页面
//                String promoterSql = combineSql("dept_id", "create_by");
//                wrapper.apply(promoterSql);
            }else if("1".equals(type)){
                //综合组派单页面
//                wrapper.eq(WorkForm::getMiddleDispatchDeptId,deptId);
                // 过滤掉已指派成功的数据
//                wrapper.ne(WorkForm::getDispatchAuditStatus, "1");
            }else if("2".equals(type) || "3".equals(type)){
                //接单情况页面和工单处理情况页面
                String receiverSql = combineSql("dealer_dept_id", "responsible_id", type);
                wrapper.apply(receiverSql);
                wrapper.eq("dispatch_audit_status", "1");
                wrapper.and(w -> w.ne("is_deferred_process", "1").or().isNull("is_deferred_process"));
            }else if("4".equals(type)){
                //企业评价页面
                String promoterSql = combineSql("dept_id", "create_by", type);
                wrapper.apply(promoterSql).eq("complete_confirmation", "3");
            } else if ("5".equals(type)) {
                // 诉求审批页面（省级账号可以看到）
                wrapper.isNotNull("dispatch_audit_status");
//                wrapper.orderByAsc(WorkForm::getDispatchAuditStatus).orderByDesc(WorkForm::getCreateTime);
//                if (StrUtil.isNotBlank(dto.getDispatchAuditStatus())) {
//                    wrapper.eq(WorkForm::getDispatchAuditStatus, dto.getDispatchAuditStatus());
//                }
            } else if ("6".equals(type)) {
                // 诉求监控页面
                String promoterSql = combineSql("dealer_dept_id", "responsible_id", type);
                wrapper.apply(promoterSql).eq("is_deferred_process", "1");
            } else{
                wrapper.apply(" 1=0 ");
            }
        } else {
            if (StrUtil.equals(type, "5")) {
                wrapper.isNotNull("dispatch_audit_status");
            } else if (StrUtil.equals(type, "6")) {
                wrapper.eq("is_deferred_process", "1");
            }
        }
//        wrapper.apply("SELECT *, CASE " +
//                                        "WHEN dispatch_time IS NOT NULL AND complete_time IS NULL AND DATEDIFF(NOW(), dispatch_time) > 30 THEN TRUE " +
//                                        "ELSE FALSE " +
//                                        "END AS is_overtime");
        wrapper.select(
                "*",
                "CASE " +
                        "WHEN dispatch_time IS NOT NULL " +
                        "AND complete_time IS NULL " +
                        "AND (EXTRACT(EPOCH FROM (NOW() - dispatch_time)) / 86400 >= 15) " +
                        "THEN TRUE " +
                        "ELSE FALSE " +
                        "END AS is_overtime"
        );
        wrapper.like(!StringUtils.isEmpty(dto.getEnterpriseName()),"enterprise_name",dto.getEnterpriseName())
                .eq(dto.getStatus() != null,"status",dto.getStatus())
                .eq(dto.getFormType() != null,"form_type",dto.getFormType())
                .eq(dto.getDealerDeptId() != null,"dealer_dept_id",dto.getDealerDeptId())
                .eq(!StringUtils.isEmpty(dto.getPolicyFormType()),"policy_form_type",dto.getPolicyFormType())
                .eq(!StringUtils.isEmpty(dto.getPolicyFormSubType()),"policy_form_sub_type",dto.getPolicyFormSubType())
                .eq(!StringUtils.isEmpty(dto.getProblemType()),"problem_type",dto.getProblemType())
                .eq(!StringUtils.isEmpty(dto.getEvaluationConfirmation()),"evaluation_confirmation",dto.getEvaluationConfirmation())
                .eq(!StringUtils.isEmpty(dto.getCreateBy()),"create_by",dto.getCreateBy())
                .eq(!StringUtils.isEmpty(dto.getProvince()),"province",dto.getProvince())
                .eq(!StringUtils.isEmpty(dto.getCity()),"city",dto.getCity())
                .eq(!StringUtils.isEmpty(dto.getCounty()),"county",dto.getCounty())
                .eq(!StringUtils.isEmpty(dto.getIndustry()),"industry",dto.getIndustry())
                .eq(!StringUtils.isEmpty(dto.getSource()),"source",dto.getSource())
                .eq(!StringUtils.isEmpty(dto.getDispatchAuditStatus()),"dispatch_audit_status",dto.getDispatchAuditStatus());
//                .orderByAsc(WorkForm::getOrderNum)
//                .orderByAsc(WorkForm::getStatus)
//                .orderByDesc(WorkForm::getCreateTime);
        if (StringUtils.isNotBlank(dto.getExpectedResponseTimeFrom()) && StringUtils.isNotBlank(dto.getExpectedResponseTimeTo())) {
            wrapper.ge("expected_response_time", LocalDate.parse(dto.getExpectedResponseTimeFrom()));
            wrapper.lt("expected_response_time", LocalDate.parse(dto.getExpectedResponseTimeTo()).plusDays(1L));
        }
        if (StringUtils.isNotBlank(dto.getCreateTimeFrom()) && StringUtils.isNotBlank(dto.getCreateTimeTo())) {
            wrapper.ge("create_time", LocalDate.parse(dto.getCreateTimeFrom()));
            wrapper.lt("create_time", LocalDate.parse(dto.getCreateTimeTo()).plusDays(1L));
        }
        if (StringUtils.isNotBlank(dto.getCompleteTimeFrom()) && StringUtils.isNotBlank(dto.getCompleteTimeTo())) {
            wrapper.ge("complete_time", LocalDate.parse(dto.getCompleteTimeFrom()));
            wrapper.lt("complete_time", LocalDate.parse(dto.getCompleteTimeTo()).plusDays(1L));
        }
        if (dto.getIsOvertime() != null) {
            // 是否超时
            if (dto.getIsOvertime()) {
                // 超时
                wrapper.apply("(dispatch_time IS NOT NULL AND complete_time IS NULL AND (EXTRACT(EPOCH FROM (NOW() - dispatch_time)) / 86400 >= 15))");
            } else {
                // 尚未超时
                wrapper.apply("NOT (dispatch_time IS NOT NULL AND complete_time IS NULL AND (EXTRACT(EPOCH FROM (NOW() - dispatch_time)) / 86400 >= 15))");
            }
        }

        // 设置排序规则
        Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(WorkForm.class);
        String orderNumColumn = columnMap.get("orderNum".toUpperCase()).getColumn();
        String statusColumn = columnMap.get("status".toUpperCase()).getColumn();
        String createTimeColumn = columnMap.get("createTime".toUpperCase()).getColumn();
        String dispatchTimeColumn = columnMap.get("dispatchTime".toUpperCase()).getColumn();
        String completeTimeColumn = columnMap.get("completeTime".toUpperCase()).getColumn();
        String evaluationTimeColumn = columnMap.get("evaluationTime".toUpperCase()).getColumn();
        String dispatchAuditStatusColumn = columnMap.get("dispatchAuditStatus".toUpperCase()).getColumn();
        String caseWhenExpression = String.format(
                "CASE %s " +
                        "WHEN 0 THEN %s " +  // status=0 时,按 createTime 排序
                        "WHEN 1 THEN %s " +  // status=1 时,按 dispatchTime 排序
                        "WHEN 2 THEN %s " +  // status=2 时,按 completeTime 排序
                        "WHEN 3 THEN %s " +  // status=3 时,按 evaluationTime 排序
                        "END DESC",          // 均为倒序
                statusColumn, createTimeColumn, dispatchTimeColumn, completeTimeColumn, evaluationTimeColumn
        );
        String orderByCommonClause = String.format("ORDER BY %s ASC, %s ASC, %s", orderNumColumn, statusColumn, caseWhenExpression);
        String orderByProvinceLevelAuditClause = String.format("ORDER BY %s ASC, %s DESC", dispatchAuditStatusColumn, createTimeColumn);
        wrapper.last(StrUtil.equals(type, "5") ? orderByProvinceLevelAuditClause : orderByCommonClause);

        return this.list(wrapper);
    }

    @Override
    public boolean dealWorkForm(WorkFormDto dto) {
        if (StrUtil.equals(dto.getDealMethod(), "延期处理")) {
            return this.update(new LambdaUpdateWrapper<WorkForm>().eq(WorkForm::getBaseId, dto.getBaseId()).set(WorkForm::getProblemReason, dto.getProblemReason()).set(WorkForm::getIsDeferredProcess, "1"));
        }
        WorkForm workForm = new WorkForm();
        BeanUtils.copyProperties(dto, workForm);
        workForm.setStatus(Byte.parseByte("2"));
        workForm.setCompleteTime(LocalDateTime.now());
        boolean update = this.updateById(workForm);
        //状态变更推送消息
        pushMessage();

        //将最新大屏数据推送给前端(位于city)
        WorkForm byId = this.getById(dto.getBaseId());
        String province = byId.getProvince();
        String city = byId.getCity();
        LargeScreenDataVo largeScreenDataVo = new LargeScreenDataVo();
        Map<String, Object> counts = getCounts(province, city, null);
//        BigDecimal settledTotal = (BigDecimal) counts.get("settledTotal");
//        BigDecimal settledRate = (BigDecimal) counts.get("settledRate");
        BigDecimal settledTotal = this.getValue(counts, "settledTotal");
        BigDecimal settledRate = this.getValue(counts, "settledRate");

        largeScreenDataVo.setSettledTotal(settledTotal.longValue());
        List<PieChartVo> serviceStatesCount = getServiceStatesCount(province, city, null);
        largeScreenDataVo.setSettledRate(settledRate.longValue());
        largeScreenDataVo.setServiceState(serviceStatesCount);
        Gson gson1 = new GsonBuilder().serializeNulls().create();
        String largeScreenDataResultJson1 = gson1.toJson(largeScreenDataVo);
        Set<String> sessionKeys1 = WebSocketManager.getSessionKeysByArea(city);
        for (String sessionKey : sessionKeys1) {
            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJson1);
        }

        //将最新大屏数据推送给前端(位于province)
        LargeScreenDataVo largeScreenDataVo1 = new LargeScreenDataVo();
        Map<String, Object> counts1 = getCounts(province, null, null);
//        BigDecimal settledTotal1 = (BigDecimal) counts1.get("settledTotal");
//        BigDecimal settledRate1 = (BigDecimal) counts1.get("settledRate");

        BigDecimal settledTotal1 = this.getValue(counts1,"settledTotal");
        BigDecimal settledRate1 = this.getValue(counts1,"settledRate");

        largeScreenDataVo1.setSettledTotal(settledTotal1.longValue());
        List<PieChartVo> serviceStatesCount1 = getServiceStatesCount(province, null, null);
        largeScreenDataVo1.setSettledRate(settledRate1.longValue());
        largeScreenDataVo1.setServiceState(serviceStatesCount1);
        Gson gson2 = new GsonBuilder().serializeNulls().create();
        String largeScreenDataResultJson2 = gson2.toJson(largeScreenDataVo1);
        Set<String> sessionKeys2 = WebSocketManager.getSessionKeysByArea(province);
        for (String sessionKey : sessionKeys2) {
            WebSocketManager.sendMessageToKey(sessionKey, largeScreenDataResultJson2);
        }

        return update;
    }

    private BigDecimal getValue(Map<String, Object> counts, String valueName) {
        BigDecimal value = new BigDecimal(0);
        Object o1 = counts.get(valueName);
        if(o1 instanceof BigDecimal) {
            value = (BigDecimal) o1;
        }else if(o1 instanceof Long ) {
            value = new BigDecimal((Long)o1);
        }else if(o1 instanceof Integer ) {
            value = new BigDecimal((Integer)o1);
        }
        return value;
    }

//    public void generateDocument(WorkFormExportDto dto, OutputStream outputStream) throws Exception {
//        Long baseId = dto.getBaseId();
//        String type = dto.getType();
//        WorkForm workForm = this.getById(baseId);
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.registerModule(new JavaTimeModule());
//        Map<String, Object> dataMap = objectMapper.convertValue(workForm, Map.class);
//
//        LocalDateTime now = LocalDateTime.now();
//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
//        dataMap.put("currentDateTime", now.format(formatter));
//
//        String dispatchDepartment = "";
//        if ("1".equals(type)) {
//            dispatchDepartment = "山东省工业运行指挥部办公室";
//        } else if ("2".equals(type)) {
//            dispatchDepartment = "山东省工业和信息化厅";
//        }
//        dataMap.put("dispatchDepartment", dispatchDepartment);
//
//        String templatePath = "file/解决企业困难诉求模版.docx";
//        InputStream templateInputStream = getClass().getClassLoader().getResourceAsStream(templatePath);
//        if (templateInputStream == null) {
//            throw new IOException("文件路径未找到: " + templatePath);
//        }
//        try {
//            WordUtils.fillTemplate(templateInputStream, outputStream, dataMap);
//        } finally {
//            templateInputStream.close(); // 确保关闭输入流
//        }
//    }

    public void generateDocument(WorkFormExportDto dto, HttpServletResponse response) throws Exception {
        String baseIds = dto.getBaseIds();
        if (StrUtil.isNotBlank(baseIds)) {
//            Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
//            configuration.setDefaultEncoding("UTF-8");
//            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
//            configuration.setDirectoryForTemplateLoading(new File("/home/bid/uploadPath/")); // 设置模板路径
//            Map<String, Object> dataModel = new HashMap<>();
//            freemarker.template.Template template = configuration.getTemplate("zhoubao.ftl");

            List<Long> baseIdList = Arrays.stream(baseIds.split(","))
                    .map(Long::valueOf)
                    .collect(Collectors.toList());
            String type = dto.getType();
            List<WorkForm> workFormList = this.list(new LambdaQueryWrapper<WorkForm>().in(WorkForm::getBaseId, baseIdList));

            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("workFormList", workFormList);

            // 添加公共字段
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
            dataMap.put("currentDateTime", now.format(formatter));

            String dispatchDepartment = "";
            if ("1".equals(type)) {
                dispatchDepartment = "山东省工业运行指挥部办公室";
            } else if ("2".equals(type)) {
                dispatchDepartment = "山东省工业和信息化厅";
            }
            dataMap.put("dispatchDepartment", dispatchDepartment);

//            // 加载模板并填充
//            String templatePath = "file/解决企业困难诉求模版.docx";
//            InputStream templateInputStream = getClass().getClassLoader().getResourceAsStream(templatePath);
//            if (templateInputStream == null) {
//                throw new IOException("文件路径未找到: " + templatePath);
//            }
//            try {
//                WordUtils.fillTemplate(templateInputStream, outputStream, dataMap);
//            } finally {
//                templateInputStream.close();
//            }

            // 1. 配置 FreeMarker
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
            configuration.setDefaultEncoding("UTF-8");
            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
//            configuration.setDirectoryForTemplateLoading(new File("D:/ruoyi/uploadPath/"));
            configuration.setDirectoryForTemplateLoading(new File("/home/services/suqiu/"));

            // 2. 加载模板
            freemarker.template.Template template = configuration.getTemplate("解决企业困难诉求模版.ftl");

            // 3. 生成临时文件路径
//            String tempFilePath = "D:/ruoyi/uploadPath/" + "temp_" + UUID.randomUUID() + ".docx";
            String tempFilePath = "/home/services/suqiu/" + "temp_" + UUID.randomUUID() + ".docx";
            Writer out = new FileWriter(tempFilePath);

            // 4. 填充数据并生成文档
            try {
                template.process(dataMap, out);
            } finally {
                out.close();
            }

            // 5. 将生成的文档写入 HTTP 响应
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("解决企业困难诉求协调函", "UTF-8") + ".docx");
            try {
                String path = FilenameUtils.getPath(tempFilePath);
                String baseName = FilenameUtils.getBaseName(tempFilePath);
                String filePathDisk = File.separator + path +  baseName + ".docx";
                FileInputStream fileInputStream = new FileInputStream(filePathDisk);
                OutputStream outputStream = response.getOutputStream();

                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }

                outputStream.flush();
                fileInputStream.close();
            } catch (IOException e) {
                // 处理异常
                e.printStackTrace();
            }
        }
    }

//    private String combineSql(String deptField, String userField, String type){
//        SysUser user = SecurityUtils.getLoginUser().getUser();
//        StringBuilder sqlString = new StringBuilder();
//        List<String> scopeCustomIds = new ArrayList<String>();
//        user.getRoles().forEach(role -> {
//            if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL))
//            {
//                scopeCustomIds.add(Convert.toStr(role.getRoleId()));
//            }
//        });
//
//        for (SysRole role : user.getRoles())
//        {
//            String dataScope = role.getDataScope();
//            if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE))
//            {
//                continue;
//            }
//
//            if (DATA_SCOPE_ALL.equals(dataScope))
//            {
//                sqlString = new StringBuilder();
//                break;
//            }
//            else if (DATA_SCOPE_CUSTOM.equals(dataScope))
//            {
//                if (scopeCustomIds.size() > 1)
//                {
//
//                    sqlString.append(StringUtils.format(" OR "+deptField+" IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", String.join(",", scopeCustomIds)));
//                }
//                else
//                {
//                    sqlString.append(StringUtils.format(" OR "+deptField+" IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", role.getRoleId()));
//                }
//            }
//            else if (DATA_SCOPE_DEPT.equals(dataScope))
//            {
//                sqlString.append(StringUtils.format(" OR "+deptField+" = '{}' ", user.getDeptId()));
//            }
//            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
//            {
//                sqlString.append(StringUtils.format(" OR "+deptField+" IN ( SELECT dept_id FROM sys_dept WHERE dept_id = '{}' or find_in_set( '{}' , ancestors ) )", user.getDeptId(), user.getDeptId()));
//            }
//            else if (DATA_SCOPE_SELF.equals(dataScope))
//            {
//                sqlString.append(StringUtils.format(" OR "+userField+" = {} ", user.getUserId()));
//            }
//            else if (DATA_SCOPE_PROVINCE_LEVEL.equals(dataScope))
//            {
//
//            }
//            else if (DATA_SCOPE_CITY_LEVEL.equals(dataScope))
//            {
//                // 市级账号
//                Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(WorkForm.class);
//                sqlString.append(StringUtils.format(" OR "+columnMap.get("secondaryDealerDeptId".toUpperCase()).getColumn()+" IN ( SELECT dept_id FROM sys_dept WHERE dept_id = '{}' or find_in_set( '{}' , ancestors ) )", user.getDeptId(), user.getDeptId()));
//            }
//            else if (DATA_SCOPE_COUNTY_LEVEL.equals(dataScope))
//            {
//                // 区县级账号
//                sqlString.append(StringUtils.format(" OR "+deptField+" = '{}' ", user.getDeptId()));
//                Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(WorkForm.class);
//                sqlString.append(StringUtils.format(" OR "+columnMap.get("secondaryDealerDeptId".toUpperCase()).getColumn()+" = '{}' ", user.getDeptId()));
//            }
//        }
//        String combineString = " (1=1) ";
//        if(!StringUtils.isEmpty(sqlString.toString())){
//            combineString = " (" + sqlString.substring(4) + ")";
//        }
//
//        return combineString;
//    }

    private String combineSql(String deptField, String userField, String type) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        StringBuilder sqlString = new StringBuilder();
        List<String> scopeCustomIds = new ArrayList<>();

        // 收集自定义权限的角色 ID
        for (SysRole role : user.getRoles()) {
            if (DATA_SCOPE_CUSTOM.equals(role.getDataScope())
                    && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL)) {
                scopeCustomIds.add(Convert.toStr(role.getRoleId()));
            }
        }

        for (SysRole role : user.getRoles()) {
            String dataScope = role.getDataScope();
            if (StringUtils.equals(role.getStatus(), UserConstants.ROLE_DISABLE)) {
                continue;
            }

            if (DATA_SCOPE_ALL.equals(dataScope)) {
                sqlString = new StringBuilder(); // 所有人可见，无需限制
                break;
            } else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
                if (scopeCustomIds.size() > 1) {
                    sqlString.append(String.format(" OR %s IN ( SELECT dept_id FROM sys_role_dept WHERE role_id IN (%s) )",
                            deptField, String.join(",", scopeCustomIds)));
                } else {
                    sqlString.append(String.format(" OR %s IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = %s )",
                            deptField, role.getRoleId()));
                }
            } else if (DATA_SCOPE_DEPT.equals(dataScope)) {
                sqlString.append(String.format(" OR %s = '%s'", deptField, user.getDeptId()));
            } else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
                // 使用 string_to_array 替代正则匹配
                sqlString.append(String.format(
                        " OR %s IN ( SELECT dept_id FROM sys_dept WHERE dept_id = '%s' OR '%s' = ANY(string_to_array(ancestors, ',')) )",
                        deptField, user.getDeptId(), user.getDeptId()));
            } else if (DATA_SCOPE_SELF.equals(dataScope)) {
                sqlString.append(String.format(" OR %s = %s", userField, user.getUserId()));
            } else if (DATA_SCOPE_PROVINCE_LEVEL.equals(dataScope)) {
                // 省级账号逻辑（可根据业务补充）
            } else if (DATA_SCOPE_CITY_LEVEL.equals(dataScope)) {
                Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(WorkForm.class);
                String secondaryDealerDeptIdColumn = columnMap.get("secondaryDealerDeptId".toUpperCase()).getColumn();
                sqlString.append(String.format(
                        " OR %s IN ( SELECT dept_id FROM sys_dept WHERE dept_id = '%s' OR '%s' = ANY(string_to_array(ancestors, ',')) )",
                        secondaryDealerDeptIdColumn, user.getDeptId(), user.getDeptId()));
                String dealerDeptIdColumn = columnMap.get("dealerDeptId".toUpperCase()).getColumn();
                sqlString.append(String.format(
                        " OR %s IN ( SELECT dept_id FROM sys_dept WHERE dept_id = '%s' OR '%s' = ANY(string_to_array(ancestors, ',')) )",
                        dealerDeptIdColumn, user.getDeptId(), user.getDeptId()));
            } else if (DATA_SCOPE_COUNTY_LEVEL.equals(dataScope)) {
                sqlString.append(String.format(" OR %s = '%s'", deptField, user.getDeptId()));

                Map<String, ColumnCache> columnMap = LambdaUtils.getColumnMap(WorkForm.class);
                String secondaryDealerDeptIdColumn = columnMap.get("secondaryDealerDeptId".toUpperCase()).getColumn();

                sqlString.append(String.format(" OR %s = '%s'", secondaryDealerDeptIdColumn, user.getDeptId()));
            }
        }

        String combineString = " (1=1) ";
        if (!StringUtils.isEmpty(sqlString.toString())) {
            combineString = " (" + sqlString.substring(4) + ")";
        }

        return combineString;
    }

    /**
     * 获取各诉求类型计数（大屏）
     */
    @Override
    public HistogramVo getAppealTypesCount(String province, String city, String county) {
        HistogramVo appealTypes= this.baseMapper.selectAppealTypesCount(province, city, county);
        return appealTypes;
    }

    /**
     * 获取各服务等级计数（大屏）
     */
    @Override
    public List<PieChartVo> getServiceGradesCount(String province, String city, String county) {
        //查询各服务等级的数量
        List<PieChartVo> pieChartVos = this.baseMapper.selectServiceGradesCount(province, city, county);
        return pieChartVos;
    }

    /**
     * 获取问题总数、已办结数以及办结率（大屏）
     */
    @Override
    public Map<String, Object> getCounts(String province, String city, String county) {
        return this.baseMapper.selectCounts(province, city, county);
    }

    /**
     * 获取各服务状态计数（大屏）
     */
    @Override
    public List<PieChartVo> getServiceStatesCount(String province, String city, String county) {
        //查询各服务状态的数量
        List<PieChartVo> pieChartVos = this.baseMapper.selectServiceStatesCount(province, city, county);
        return pieChartVos;
    }

    /**
     * 获取企业满意度比例（大屏）
     */
    @Override
    public List<PieChartVo> getEnterpriseSatisfactionRatio(String province, String city, String county) {
        //查询企业满意度比例
        List<PieChartVo> pieChartVos = this.baseMapper.selectEnterpriseSatisfactionRatio(province, city, county);
        return pieChartVos;
    }

    /**
     * 获取各地市诉求数量计数（大屏）
     */
    @Override
    public HistogramVo getCitiesAppealQuantityCount(String province, String city, String county) {
        HistogramVo citiesAppealQuantity = this.baseMapper.selectCitiesAppealQuantityCount(province, city, county);
        return citiesAppealQuantity;
    }

    @Override
    public Map workFormStatistic(FormExportFilterDto dto) {
        if(dto.getYear() != null && dto.getMonth() != null){
            Date date = getDate(dto.getYear(), dto.getMonth());
            dto.setFilterDate(date);
        }
        FormDealVo formDealVo = this.getBaseMapper().formCount(dto);
        List<FormTypeCountVo> formTypeCountVos = this.getBaseMapper().formTypeCount(dto);
         List<FormDealFeedBackPielVo> formDealFeedBackPielVos = this.getBaseMapper().formCountPieChart(dto);
        List<FormCityCountVo> formCityCountVos = this.getBaseMapper().formCitiesCount(dto);
        Long increasedEnterpriseCount = sysUserService.getIncreasedEnterpriseCount(dto.getDateBegin(), dto.getDateEnd());
        Map map = new HashMap();
        map.put("formDealInfo", formDealVo);
        map.put("formTypeDistribution", formTypeCountVos);
        map.put("formCityDistribution", formCityCountVos);
        map.put("satisfactionInfo", formDealFeedBackPielVos);
        map.put("increasedEnterpriseCount", increasedEnterpriseCount);
        return map;
    }

    @Override
    public void sendBatch(WorkFormDto dto) {
        List<Long> formIdList = dto.getFormIdList();
        if(formIdList != null && formIdList.size() > 0){
            this.update(new LambdaUpdateWrapper<WorkForm>().in(WorkForm::getBaseId, formIdList).set(WorkForm::getSecondaryDealerDeptId, dto.getSecondaryDealerDeptId())
                    .set(WorkForm::getSecondaryDealerDeptName, dto.getSecondaryDealerDeptName())
                    .set(WorkForm::getIsConfirm, "0"));
        }
    }

    @Override
    public AjaxResult confirmSent(String baseId) {
        String deptId = SecurityUtils.getDeptId();
        WorkForm byId = this.getById(Long.valueOf(baseId));
        if ("1".equals(byId.getIsConfirm())) {
            return AjaxResult.error("确认失败，该诉求已被确认！");
        }
        String secondaryDealerDeptId = byId.getSecondaryDealerDeptId();
        if (StrUtil.isNotBlank(secondaryDealerDeptId)) {
            // 确认转交过来的诉求
            if (! StrUtil.equals(deptId, secondaryDealerDeptId)) {
                return AjaxResult.error("确认失败，您不是该诉求的确认方！");
            }
        } else {
            // 确认直接指派过来的诉求
            String dealerDeptId = byId.getDealerDeptId();
            if (! StrUtil.equals(deptId, dealerDeptId)) {
                return AjaxResult.error("确认失败，您不是该诉求的确认方！");
            }
        }

        update(new LambdaUpdateWrapper<WorkForm>().eq(WorkForm::getBaseId, Long.valueOf(baseId)).set(WorkForm::getIsConfirm, "1").set(WorkForm::getConfirmTime, LocalDateTime.now()));
        return AjaxResult.success("确认成功！");
    }

    private void pushMessage() {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        String iShandongLoginname = user.getIShandongLoginname();
        String loginSource = user.getLoginSource();
        String nickName = user.getNickName();
        if(!StringUtils.isEmpty(iShandongLoginname)){
            if("1".equals(loginSource)){//爱山东
                PushMessageDto dto = PushMessageDto.builder()
                        .title("【企业诉求处理状态变更通知】")
                        .companyName(nickName)
                        .userName(iShandongLoginname)
                        .templateId("80bd04a2b2a443ef8e619858f82b99fa").build();
                HttpResponse httpResponse = pushMessageService.pushMessage(dto);

                String body = httpResponse.body();
                JSONObject jsonObject = JSONObject.parseObject(body);
                boolean resultFlag = (Boolean)jsonObject.get("success");
                if(resultFlag){
                    log.info("给企业名称：{}推送爱山东app消息成功", nickName);
                }else{
                    String errorMessage = (String)jsonObject.get("message");
                    log.error("给企业名称：{}推送爱山东app消息失败，失败原因：{}", nickName, errorMessage);
                }

            }
        }


    }

    private Date getDate(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        cal.add(Calendar.MONTH, 1);

        return cal.getTime();
    }

    @Override
    public Map<String, Long> dataStatistics() {
        Map<String, Long> resultMap = this.baseMapper.selectDataStatistics();
        return resultMap;
    }

    @Override
    public void updateWorkForm(WorkFormDto dto) {
        WorkForm workForm = new WorkForm();
        BeanUtils.copyProperties(dto, workForm);
        workForm.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
        workForm.setUpdateTime(LocalDateTime.now());
        this.updateById(workForm);
    }

    @Override
    public void uploadSupplement(WorkFormDto dto) {
        workFormSupplementService.remove(new LambdaQueryWrapper<WorkFormSupplement>().eq(WorkFormSupplement::getFormId, dto.getBaseId()));
        List<WorkFormSupplement> supplements = dto.getSupplements();
        if (supplements != null && supplements.size() > 0) {
            // 存储补充附件
            List<WorkFormSupplement> supplementList = supplements.stream().peek(i -> i.setFormId(dto.getBaseId())).collect(Collectors.toList());
            workFormSupplementService.saveBatch(supplementList);
        }
    }

    @Override
    public boolean isDuplicatedWorkForm(String param) {
        return workFormMapper.isDuplicatedWorkForm(param) > 0;
    }

    @Override
    public void updateStatus(WorkFormDto dto) {
        LambdaUpdateWrapper<WorkForm> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(WorkForm::getBaseId, dto.getBaseId());
        Byte status = dto.getStatus();
        wrapper.set(WorkForm::getStatus, dto.getStatus());
        if (status == 0) {
            // 若更新成待处理状态，则需将 problemType、dispatchTime、dealerDeptId、dealerDeptName、summaryExperience、evaluationConfirmation、evaluationTime、feedback、completeTime、
            // dispatchAuditStatus、dispatchAuditTime、secondaryDealerDeptName、secondaryDealerDeptId、isConfirm、confirmTime、isDeferredProcess、dispatchRemark、feedbackQualityGrading 设置为空
            wrapper.set(WorkForm::getProblemType, null);
            wrapper.set(WorkForm::getDispatchTime, null);
            wrapper.set(WorkForm::getDealerDeptId, null);
            wrapper.set(WorkForm::getDealerDeptName, null);
            wrapper.set(WorkForm::getSummaryExperience, null);
            wrapper.set(WorkForm::getEvaluationConfirmation, null);
            wrapper.set(WorkForm::getEvaluationTime, null);
            wrapper.set(WorkForm::getFeedback, null);
            wrapper.set(WorkForm::getCompleteTime, null);
            wrapper.set(WorkForm::getDispatchAuditStatus, null);
            wrapper.set(WorkForm::getDispatchAuditTime, null);
            wrapper.set(WorkForm::getSecondaryDealerDeptName, null);
            wrapper.set(WorkForm::getSecondaryDealerDeptId, null);
            wrapper.set(WorkForm::getIsConfirm, null);
            wrapper.set(WorkForm::getConfirmTime, null);
            wrapper.set(WorkForm::getIsDeferredProcess, null);
            wrapper.set(WorkForm::getDispatchRemark, null);
            wrapper.set(WorkForm::getFeedbackQualityGrading, null);
        } else if (status == 1) {
            wrapper.set(WorkForm::getSummaryExperience, null);
            wrapper.set(WorkForm::getEvaluationConfirmation, null);
            wrapper.set(WorkForm::getEvaluationTime, null);
            wrapper.set(WorkForm::getFeedback, null);
            wrapper.set(WorkForm::getCompleteTime, null);
            wrapper.set(WorkForm::getDispatchAuditStatus, "1");
            wrapper.set(WorkForm::getIsConfirm, "1");
            wrapper.set(WorkForm::getIsDeferredProcess, null);
            wrapper.set(WorkForm::getFeedbackQualityGrading, null);
        } else if (status == 2) {
            wrapper.set(WorkForm::getDispatchAuditStatus, "1");
            wrapper.set(WorkForm::getIsConfirm, "1");
            wrapper.set(WorkForm::getCompleteTime, LocalDateTime.now());
            wrapper.set(WorkForm::getEvaluationConfirmation, null);
            wrapper.set(WorkForm::getEvaluationTime, null);
            wrapper.set(WorkForm::getFeedback, null);
        } else {
            wrapper.set(WorkForm::getDispatchAuditStatus, "1");
            wrapper.set(WorkForm::getIsConfirm, "1");
            wrapper.set(WorkForm::getCompleteTime, LocalDateTime.now());
            wrapper.set(WorkForm::getEvaluationConfirmation, "满意");
            wrapper.set(WorkForm::getEvaluationTime, LocalDateTime.now());
        }
        this.update(wrapper);
    }
}
